
#include <cstdio>
#include <BStyle>
#include <BListItem>
#include <BHBoxLayout>

#include "panels/ObjectPanel.h"
#include "panels/GroupPanel.h"
#include "panels/NodePanel.h"
#include "panels/ShapePanel.h"
#include "panels/MeshPanel.h"
#include "panels/GeometryPanel.h"
#include "PropertyBoard.h"

PropertyBoard::PropertyBoard(BWidget* parent) : BScrollWidget(parent)
{
	this->setAreaPolicy(Policy_Dynamic, Policy_Preferred);

	_typedPanelMap["BObject"] = new ObjectPanel();
	_typedPanelMap["BGroup"] = new GroupPanel();
	_typedPanelMap["BNode"] = new NodePanel();
	_typedPanelMap["BShape"] = new ShapePanel();
	_typedPanelMap["BMesh"] = new MeshPanel();
	_typedPanelMap["BGeometry"] = new GeometryPanel();

	_listWidget = new BListWidget();
	_listWidget->setTitle("Selected Objects");

	connect("target-changed", &PropertyBoard::slotTargetChanged);
	connect(this, Signal_AssetChanged, &PropertyBoard::slotAssetChanged);
}
PropertyBoard::~PropertyBoard()
{

}

void PropertyBoard::setScene(BScene* scene)
{
	_scene = scene;
}
BScene* PropertyBoard::scene() const
{
	return _scene;
}

void PropertyBoard::freshListItemIcons()
{
	const BStyle* style = this->realStyle();
	BIcon* unknownIcon = style->icon("unknown");
	for (int i = 0; i < _listWidget->itemCount(); i++)
	{
		BListItem* item = _listWidget->item(i);
		BObject* object = item->asset();
		BIcon* typedIcon = style->icon(object->className());
		if (typedIcon)
			item->setIcon(typedIcon);
		else
			item->setIcon(unknownIcon);
	}
}

void PropertyBoard::slotAssetChanged(BObject* object, const BValue& value)
{
	BObject* obj = value;
	for (int i = 0; i < this->widgetCount(); i++)
	{
		BWidget* panel = this->widget(i);
		panel->setAsset(BValue());
	}
	this->clearWidgets();
	if (obj == 0)
	{
		_listWidget->clearItems();
		this->addWidget(_listWidget);
		return;
	}
	for (int i = 0; i < obj->typeCount(); i++)
	{
		const char* type = obj->typeName(i);
		if (BGroupBox* panel = _typedPanelMap[type])
		{
			panel->setAsset(value);
			this->addWidget(panel);
		}
	}
}
void PropertyBoard::slotTargetChanged(BObject* object, const BValue& value)
{
	if (Target* target = value)
	{
		if (BObject* object = target->object())
		{
			this->setAsset(object);
			return;
		}
		this->setAsset(BValue());
		this->clearWidgets();
		_listWidget->clearItems();
		if (target->pickHitCount() > 1)
		{
			this->addWidget(_listWidget);
			_listWidget->clearItems();
			for (int i = 0; i < target->pickHitCount(); i++)
			{
				BPickHit* pickHit= target->pickHit(i);
				BListItem* listItem = new BListItem();
				if (BShape* shape = pickHit->shape())
				{
					listItem->setText(shape->name());
					listItem->setAsset(shape);
				}
				else if (BNode* node = pickHit->node())
				{
					listItem->setText(node->name());
					listItem->setAsset(node);
				}
				else if (BGroup* group = pickHit->group())
				{
					listItem->setText(group->name());
					listItem->setAsset(group);
				}
				listItem->setProperty("element", pickHit->element());
				_listWidget->addItem(listItem);
			}
			this->freshListItemIcons();
			return;
		}
	}
}
